; Copyright 2013 padnest@gmail.com

; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
;   http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.


; Extension language for pic18f family

; Moves literal value to file register.
; lit: literal value to move
; freg: the target file register
; Affects: WREG, STATUS
; Cycles: 2
movlf macro lit, freg
    movlw   lit
    movwf   freg
    endm


; Shifts to left freg content by pos.
; freg: the file register to shift left
; pos: a literal containing the number of bits to shift left
; Affects: WREG, STATUS
; Cycles: 2 if pos=1, 4 if pos=2, 5 if pos=3, 3 if pos=4, 4 if pos=5, 5 if pos=6, 3 if pos=7
shftlf macro freg, pos
    local n
    if pos < 4           
        n = pos                     ; pos: 1 to 3
        while n > 0
            rlcf    freg, f
            n--
        endw
        if pos == 1
            bcf     freg, 0
        else
            movlw   (0xFF << pos)
            andwf   freg, f
        endif
    else
        if pos < 6
            if pos == 4
                swapf   freg, f      ; pos == 4
                movlw   0xF0
                andwf   freg, f
            else
                swapf   freg, f      ; pos == 5
                rlcf    freg, f
                movlw   0xE0
                andwf   freg, f
            endif
        else
            if pos == 6
                swapf   freg, f      ; pos == 6
                rlcf    freg, f
                rlcf    freg, f
                movlw   0xC0
                andwf   freg, f
            else                    
                rrcf    freg, f      ; pos == 7
                clrf    freg
                rrcf    freg, f
            endif
        endif
    endif
    endm

; Shifts to right freg content by pos.
; freg: the file register to shift right
; pos: a literal containing the number of bits to shift right
; Affects: WREG, STATUS
; Cycles: 2 if pos=1, 4 if pos=2, 5 if pos=3, 3 if pos=4, 4 if pos=5, 5 if pos=6, 3 if pos=7
shftrf macro freg, pos
    local n
    if pos < 4
        n = pos                     ; pos: 1 to 3
        while n > 0
            rrcf    freg, f
            n--
        endw
        if pos == 1
            bcf     freg, 7
        else
            movlw   (0xFF >> pos)
            andwf   freg, f
        endif
    else
        if pos < 6
            if pos == 4
                swapf   freg, f      ; pos == 4
                movlw   0x0F
                andwf   freg, f
            else
                swapf   freg, f      ; pos == 5
                rrcf    freg, f
                movlw   0x07
                andwf   freg, f
            endif
        else
            if pos == 6
                swapf   freg, f      ; pos == 6
                rrcf    freg, f
                rrcf    freg, f
                movlw   0x03
                andwf   freg, f
            else
                rlcf    freg, f      ; pos == 7
                clrf    freg
                rlcf    freg, f
            endif
        endif
    endif
    endm